from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from django.db.models import Q, Sum, Count, F
from django.utils import timezone
from datetime import datetime, timedelta
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill
from django.http import HttpResponse
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from io import BytesIO
from .models import StockIn, StockInDetail, StockOut, StockOutDetail, StockRecord, StockCheck, StockCheckDetail, StockTransfer, StockTransferDetail
from .serializers import (
    StockInSerializer, StockInDetailSerializer,
    StockOutSerializer, StockOutDetailSerializer,
    StockRecordSerializer,
    StockCheckSerializer, StockCheckDetailSerializer,
    StockTransferSerializer, StockTransferDetailSerializer
)
from product.models import Product
from product.serializers import ProductSerializer
from warehouse_system.pagination import StandardResultsSetPagination
from .utils import (
    update_stock_in_status, update_stock_out_status,
    update_stock_check_status, update_stock_transfer_status
)
import os

class StockInViewSet(viewsets.ModelViewSet):
    queryset = StockIn.objects.all()
    serializer_class = StockInSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination

    def get_permissions(self):
        if self.action in ['destroy']:
            return [IsAdminUser()]
        return [IsAuthenticated()]

    def get_queryset(self):
        queryset = super().get_queryset()
        stock_in_no = self.request.query_params.get('stock_in_no')
        begin_time = self.request.query_params.get('beginTime')
        end_time = self.request.query_params.get('endTime')

        if stock_in_no:
            queryset = queryset.filter(stock_in_no__icontains=stock_in_no)
        
        if begin_time:
            try:
                begin_time = datetime.strptime(begin_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__gte=begin_time)
            except ValueError:
                pass
        
        if end_time:
            try:
                end_time = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__lte=end_time)
            except ValueError:
                pass
        
        return queryset

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        # 获取新创建的入库单对象
        stock_in = serializer.instance

        # 使用 StockInSerializer 序列化入库单对象
        stock_in_data = StockInSerializer(stock_in).data

        # 构建自定义响应格式
        response_data = {
            "code": 1,
            "data": {
                "id": stock_in_data['id'],
                "stock_in_no": stock_in_data['stock_in_no'],
                "supplier": {
                    "id": stock_in_data['supplier']['id'],
                    "name": stock_in_data['supplier']['name'],
                    "contact": stock_in_data['supplier']['contact'],
                    "phone": stock_in_data['supplier']['phone'],
                    "address": stock_in_data['supplier']['address'],
                    "status": stock_in_data['supplier']['status']
                },
                "total_amount": stock_in_data['total_amount'],
                "status": stock_in_data['status'],
                "create_user": {
                    "id": stock_in_data['create_user']['id'],
                    "username": stock_in_data['create_user']['username'],
                    "name": stock_in_data['create_user']['name']
                },
                "create_time": stock_in_data['create_time'],
                "update_time": stock_in_data['update_time'],
                "details": [
                    {
                        "id": detail['id'],
                        "product": {
                            "id": detail['product']['id'],
                            "name": detail['product']['name'],
                            "code": detail['product']['code'],
                            "unit": detail['product']['unit']
                        },
                        "price": detail['price'],
                        "quantity": detail['quantity'],
                        "amount": detail['amount']
                    } for detail in stock_in_data['details']
                ]
            }
        }

        headers = self.get_success_headers(serializer.data)
        return Response(response_data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save(create_user=self.request.user)

    @action(detail=True, methods=['post'])
    def status(self, request, pk=None):
        status = request.data.get('status')
        if status not in [0, 1]:
            return Response({'code': 0, 'msg': '状态值无效'}, status=status.HTTP_400_BAD_REQUEST)
        
        stock_in = self.get_object()
        success, msg = update_stock_in_status(stock_in, status, request.user)
        if not success:
            return Response({'code': 0, 'msg': msg}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'code': 1, 'data': None})

    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取入库统计信息"""
        today = timezone.now().date()
        week_ago = today - timedelta(days=7)
        month_ago = today - timedelta(days=30)

        # 今日统计
        today_stats = StockIn.objects.filter(
            create_time__date=today
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )

        # 本周统计
        week_stats = StockIn.objects.filter(
            create_time__date__gte=week_ago
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )

        # 本月统计
        month_stats = StockIn.objects.filter(
            create_time__date__gte=month_ago
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )

        return Response({
            'code': 1,
            'data': {
                'today': today_stats,
                'week': week_stats,
                'month': month_stats
            }
        })

    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出入库单"""
        # 获取查询参数
        stock_in_no = request.query_params.get('stock_in_no')
        begin_time = request.query_params.get('beginTime')
        end_time = request.query_params.get('endTime')
        
        # 构建查询
        queryset = self.get_queryset()
        
        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "入库单"
        
        # 设置表头样式
        header_font = Font(bold=True)
        header_fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
        header_alignment = Alignment(horizontal='center', vertical='center')
        
        # 写入表头
        headers = ['入库单号', '供应商', '商品编码', '商品名称', '入库价格', '入库数量', '金额', 
                  '状态', '创建人', '创建时间']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
        
        # 写入数据
        row = 2
        for stock_in in queryset:
            for detail in stock_in.details.all():
                ws.cell(row=row, column=1).value = stock_in.stock_in_no
                ws.cell(row=row, column=2).value = stock_in.supplier.name
                ws.cell(row=row, column=3).value = detail.product.code
                ws.cell(row=row, column=4).value = detail.product.name
                ws.cell(row=row, column=5).value = float(detail.price)
                ws.cell(row=row, column=6).value = detail.quantity
                ws.cell(row=row, column=7).value = float(detail.amount)
                ws.cell(row=row, column=8).value = '已审核' if stock_in.status == 1 else '待审核'
                ws.cell(row=row, column=9).value = stock_in.create_user.name
                ws.cell(row=row, column=10).value = stock_in.create_time.strftime('%Y-%m-%d %H:%M:%S')
                row += 1
        
        # 调整列宽
        for col in ws.columns:
            max_length = 0
            column = col[0].column_letter
            for cell in col:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            adjusted_width = (max_length + 2)
            ws.column_dimensions[column].width = adjusted_width
        
        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename=stock_in.xlsx'
        
        # 保存工作簿
        wb.save(response)
        return response

    @action(detail=True, methods=['get'])
    def print(self, request, pk=None):
        """打印入库单"""
        stock_in = self.get_object()
        
        # 创建响应
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = f'attachment; filename="{stock_in.stock_in_no}.pdf"'
        
        # 创建PDF文档
        buffer = BytesIO()
        doc = SimpleDocTemplate(buffer, pagesize=A4)
        elements = []
        
        # 获取样式
        styles = getSampleStyleSheet()
        title_style = ParagraphStyle(
            'CustomTitle',
            parent=styles['Heading1'],
            fontSize=16,
            alignment=1,
            spaceAfter=30
        )
        
        # 添加标题
        elements.append(Paragraph(f'Stock In - {stock_in.stock_in_no}', title_style))
        
        # 添加基本信息
        data = [
            ['Supplier', stock_in.supplier.name],
            ['Create Time', stock_in.create_time.strftime('%Y-%m-%d %H:%M:%S')],
            ['Creator', stock_in.create_user.name],
            ['Total Amount', f'¥{stock_in.total_amount}']
        ]
        
        # 创建表格
        table = Table(data, colWidths=[100, 400])
        table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ]))
        elements.append(table)
        elements.append(Spacer(1, 20))
        
        # 添加明细信息
        details_data = [['Product', 'Price', 'Quantity', 'Amount']]
        for detail in stock_in.details.all():
            details_data.append([
                detail.product.name,
                f'¥{detail.price}',
                str(detail.quantity),
                f'¥{detail.amount}'
            ])
        
        details_table = Table(details_data, colWidths=[200, 100, 100, 100])
        details_table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('BACKGROUND', (0, 0), (3, 0), colors.lightgrey),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ]))
        elements.append(details_table)
        
        # 生成PDF
        doc.build(elements)
        pdf = buffer.getvalue()
        buffer.close()
        response.write(pdf)
        
        return response

class StockOutViewSet(viewsets.ModelViewSet):
    queryset = StockOut.objects.all()
    serializer_class = StockOutSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination

    def get_permissions(self):
        if self.action in ['destroy']:
            return [IsAdminUser()]
        return [IsAuthenticated()]

    def get_queryset(self):
        queryset = super().get_queryset()
        stock_out_no = self.request.query_params.get('stock_out_no')
        begin_time = self.request.query_params.get('beginTime')
        end_time = self.request.query_params.get('endTime')

        if stock_out_no:
            queryset = queryset.filter(stock_out_no__icontains=stock_out_no)
        
        if begin_time:
            try:
                begin_time = datetime.strptime(begin_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__gte=begin_time)
            except ValueError:
                pass
        
        if end_time:
            try:
                end_time = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__lte=end_time)
            except ValueError:
                pass
        
        return queryset

    def perform_create(self, serializer):
        serializer.save(create_user=self.request.user)

    @action(detail=True, methods=['post'])
    def status(self, request, pk=None):
        status = request.data.get('status')
        if status not in [0, 1]:
            return Response({'code': 0, 'msg': '状态值无效'}, status=status.HTTP_400_BAD_REQUEST)
        
        stock_out = self.get_object()
        success, msg = update_stock_out_status(stock_out, status, request.user)
        if not success:
            return Response({'code': 0, 'msg': msg}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'code': 1, 'data': None})

    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取出库统计信息"""
        today = timezone.now().date()
        week_ago = today - timedelta(days=7)
        month_ago = today - timedelta(days=30)

        # 今日统计
        today_stats = StockOut.objects.filter(
            create_time__date=today
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )

        # 本周统计
        week_stats = StockOut.objects.filter(
            create_time__date__gte=week_ago
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )

        # 本月统计
        month_stats = StockOut.objects.filter(
            create_time__date__gte=month_ago
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )

        return Response({
            'code': 1,
            'data': {
                'today': today_stats,
                'week': week_stats,
                'month': month_stats
            }
        })

    @action(detail=False, methods=['get'])
    def stock_warning(self, request):
        """获取库存预警信息"""
        warning_products = Product.objects.filter(
            stock__lte=F('warning_stock')
        ).values('id', 'name', 'code', 'stock', 'warning_stock')

        return Response({
            'code': 1,
            'data': list(warning_products)
        })

    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出出库单"""
        # 获取查询参数
        stock_out_no = request.query_params.get('stock_out_no')
        begin_time = request.query_params.get('beginTime')
        end_time = request.query_params.get('endTime')
        
        # 构建查询
        queryset = self.get_queryset()
        
        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "出库单"
        
        # 设置表头样式
        header_font = Font(bold=True)
        header_fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
        header_alignment = Alignment(horizontal='center', vertical='center')
        
        # 写入表头
        headers = ['出库单号', '客户', '商品编码', '商品名称', '出库价格', '出库数量', '金额', 
                  '状态', '创建人', '创建时间']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
        
        # 写入数据
        row = 2
        for stock_out in queryset:
            for detail in stock_out.details.all():
                ws.cell(row=row, column=1).value = stock_out.stock_out_no
                ws.cell(row=row, column=2).value = stock_out.customer.name
                ws.cell(row=row, column=3).value = detail.product.code
                ws.cell(row=row, column=4).value = detail.product.name
                ws.cell(row=row, column=5).value = float(detail.price)
                ws.cell(row=row, column=6).value = detail.quantity
                ws.cell(row=row, column=7).value = float(detail.amount)
                ws.cell(row=row, column=8).value = '已审核' if stock_out.status == 1 else '待审核'
                ws.cell(row=row, column=9).value = stock_out.create_user.name
                ws.cell(row=row, column=10).value = stock_out.create_time.strftime('%Y-%m-%d %H:%M:%S')
                row += 1
        
        # 调整列宽
        for col in ws.columns:
            max_length = 0
            column = col[0].column_letter
            for cell in col:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            adjusted_width = (max_length + 2)
            ws.column_dimensions[column].width = adjusted_width
        
        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename=stock_out.xlsx'
        
        # 保存工作簿
        wb.save(response)
        return response

    @action(detail=True, methods=['get'])
    def print(self, request, pk=None):
        """打印出库单"""
        stock_out = self.get_object()
        
        # 创建PDF文件
        buffer = BytesIO()
        doc = SimpleDocTemplate(buffer, pagesize=A4)
        elements = []
        
        # 获取样式
        styles = getSampleStyleSheet()
        title_style = ParagraphStyle(
            'CustomTitle',
            parent=styles['Heading1'],
            fontSize=16,
            alignment=1,
            spaceAfter=30
        )
        
        # 添加标题
        elements.append(Paragraph('Stock Out', title_style))
        elements.append(Spacer(1, 20))
        
        # 添加基本信息
        info_data = [
            ['Stock Out No:', stock_out.stock_out_no, 'Customer:', stock_out.customer.name],
            ['Creator:', stock_out.create_user.name, 'Create Time:', stock_out.create_time.strftime('%Y-%m-%d %H:%M:%S')],
            ['Status:', 'Approved' if stock_out.status == 1 else 'Pending', '', '']
        ]
        
        info_table = Table(info_data, colWidths=[80, 150, 80, 150])
        info_table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('PADDING', (0, 0), (-1, -1), 6),
        ]))
        elements.append(info_table)
        elements.append(Spacer(1, 20))
        
        # 添加明细表头
        headers = ['Product Code', 'Product Name', 'Price', 'Quantity', 'Amount']
        data = [headers]
        
        # 添加明细数据
        total_amount = 0
        for detail in stock_out.details.all():
            row = [
                detail.product.code,
                detail.product.name,
                str(detail.price),
                str(detail.quantity),
                str(detail.amount)
            ]
            data.append(row)
            total_amount += detail.amount
        
        # 添加合计行
        data.append(['Total', '', '', '', str(total_amount)])
        
        # 创建明细表格
        col_widths = [100, 200, 100, 100, 100]
        table = Table(data, colWidths=col_widths)
        table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('PADDING', (0, 0), (-1, -1), 6),
            ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, -1), (-1, -1), 'RIGHT'),
            ('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),
        ]))
        elements.append(table)
        
        # 生成PDF
        doc.build(elements)
        buffer.seek(0)
        
        # 创建响应
        response = HttpResponse(buffer.getvalue(), content_type='application/pdf')
        response['Content-Disposition'] = f'attachment; filename=stock_out_{stock_out.stock_out_no}.pdf'
        return response

class StockRecordViewSet(viewsets.ReadOnlyModelViewSet):
    """库存流水记录视图集"""
    queryset = StockRecord.objects.all()
    serializer_class = StockRecordSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination
    
    def get_queryset(self):
        queryset = super().get_queryset()
        product_id = self.request.query_params.get('product_id')
        type = self.request.query_params.get('type')
        begin_time = self.request.query_params.get('beginTime')
        end_time = self.request.query_params.get('endTime')
        
        if product_id:
            queryset = queryset.filter(product_id=product_id)
        if type:
            queryset = queryset.filter(type=type)
        if begin_time:
            try:
                begin_time = datetime.strptime(begin_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__gte=begin_time)
            except ValueError:
                pass
        if end_time:
            try:
                end_time = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__lte=end_time)
            except ValueError:
                pass
        
        return queryset

    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出库存报表"""
        # 获取查询参数
        product_id = request.query_params.get('product_id')
        type = request.query_params.get('type')
        begin_time = request.query_params.get('beginTime')
        end_time = request.query_params.get('endTime')
        
        # 构建查询
        queryset = self.get_queryset()
        
        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "库存报表"
        
        # 设置表头样式
        header_font = Font(bold=True)
        header_fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
        header_alignment = Alignment(horizontal='center', vertical='center')
        
        # 写入表头
        headers = ['商品编码', '商品名称', '操作类型', '操作数量', '操作前库存', '操作后库存', 
                  '关联单号', '备注', '操作人', '操作时间']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
        
        # 写入数据
        row = 2
        for record in queryset:
            ws.cell(row=row, column=1).value = record.product.code
            ws.cell(row=row, column=2).value = record.product.name
            ws.cell(row=row, column=3).value = record.get_type_display()
            ws.cell(row=row, column=4).value = record.quantity
            ws.cell(row=row, column=5).value = record.before_stock
            ws.cell(row=row, column=6).value = record.after_stock
            ws.cell(row=row, column=7).value = record.related_no
            ws.cell(row=row, column=8).value = record.remark
            ws.cell(row=row, column=9).value = record.create_user.name
            ws.cell(row=row, column=10).value = record.create_time.strftime('%Y-%m-%d %H:%M:%S')
            row += 1
        
        # 调整列宽
        for col in ws.columns:
            max_length = 0
            column = col[0].column_letter
            for cell in col:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            adjusted_width = (max_length + 2)
            ws.column_dimensions[column].width = adjusted_width
        
        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename=stock_record.xlsx'
        
        # 保存工作簿
        wb.save(response)
        return response

class StockCheckViewSet(viewsets.ModelViewSet):
    """库存盘点视图集"""
    queryset = StockCheck.objects.all()
    serializer_class = StockCheckSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination
    
    def get_permissions(self):
        if self.action in ['destroy']:
            return [IsAdminUser()]
        return [IsAuthenticated()]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        check_no = self.request.query_params.get('check_no')
        begin_time = self.request.query_params.get('beginTime')
        end_time = self.request.query_params.get('endTime')
        
        if check_no:
            queryset = queryset.filter(check_no__icontains=check_no)
        if begin_time:
            try:
                begin_time = datetime.strptime(begin_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__gte=begin_time)
            except ValueError:
                pass
        if end_time:
            try:
                end_time = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__lte=end_time)
            except ValueError:
                pass
        
        return queryset
    
    def perform_create(self, serializer):
        serializer.save(create_user=self.request.user)
    
    @action(detail=True, methods=['post'])
    def status(self, request, pk=None):
        """更新盘点单状态"""
        status = request.data.get('status')
        if status not in [0, 1]:
            return Response({'code': 0, 'msg': '状态值无效'}, status=status.HTTP_400_BAD_REQUEST)
        
        stock_check = self.get_object()
        success, msg = update_stock_check_status(stock_check, status, request.user)
        if not success:
            return Response({'code': 0, 'msg': msg}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'code': 1, 'data': None})
    
    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取盘点统计信息"""
        today = timezone.now().date()
        week_ago = today - timedelta(days=7)
        month_ago = today - timedelta(days=30)
        
        # 今日统计
        today_stats = StockCheck.objects.filter(
            create_time__date=today
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )
        
        # 本周统计
        week_stats = StockCheck.objects.filter(
            create_time__date__gte=week_ago
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )
        
        # 本月统计
        month_stats = StockCheck.objects.filter(
            create_time__date__gte=month_ago
        ).aggregate(
            total_count=Count('id'),
            total_amount=Sum('total_amount')
        )
        
        return Response({
            'code': 1,
            'data': {
                'today': today_stats,
                'week': week_stats,
                'month': month_stats
            }
        })

    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出库存盘点报表"""
        # 获取查询参数
        check_no = request.query_params.get('check_no')
        begin_time = request.query_params.get('beginTime')
        end_time = request.query_params.get('endTime')
        
        # 构建查询
        queryset = self.get_queryset()
        
        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "库存盘点报表"
        
        # 设置表头样式
        header_font = Font(bold=True)
        header_fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
        header_alignment = Alignment(horizontal='center', vertical='center')
        
        # 写入表头
        headers = ['盘点单号', '商品编码', '商品名称', '系统库存', '实际库存', '差异数量', 
                  '差异金额', '状态', '备注', '创建人', '创建时间']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
        
        # 写入数据
        row = 2
        for check in queryset:
            for detail in check.details.all():
                ws.cell(row=row, column=1).value = check.check_no
                ws.cell(row=row, column=2).value = detail.product.code
                ws.cell(row=row, column=3).value = detail.product.name
                ws.cell(row=row, column=4).value = detail.system_stock
                ws.cell(row=row, column=5).value = detail.actual_stock
                ws.cell(row=row, column=6).value = detail.difference
                ws.cell(row=row, column=7).value = detail.amount
                ws.cell(row=row, column=8).value = check.get_status_display()
                ws.cell(row=row, column=9).value = detail.remark
                ws.cell(row=row, column=10).value = check.create_user.name
                ws.cell(row=row, column=11).value = check.create_time.strftime('%Y-%m-%d %H:%M:%S')
                row += 1
        
        # 调整列宽
        for col in ws.columns:
            max_length = 0
            column = col[0].column_letter
            for cell in col:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            adjusted_width = (max_length + 2)
            ws.column_dimensions[column].width = adjusted_width
        
        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename=stock_check.xlsx'
        
        # 保存工作簿
        wb.save(response)
        return response

    @action(detail=True, methods=['get'])
    def print(self, request, pk=None):
        """打印盘点单"""
        stock_check = self.get_object()
        
        # 创建PDF文件
        buffer = BytesIO()
        doc = SimpleDocTemplate(buffer, pagesize=A4)
        elements = []
        
        # 获取样式
        styles = getSampleStyleSheet()
        title_style = ParagraphStyle(
            'CustomTitle',
            parent=styles['Heading1'],
            fontSize=16,
            alignment=1,
            spaceAfter=30
        )
        
        # 添加标题
        elements.append(Paragraph('Stock Check', title_style))
        elements.append(Spacer(1, 20))
        
        # 添加基本信息
        info_data = [
            ['Check No:', stock_check.check_no, 'Creator:', stock_check.create_user.name],
            ['Create Time:', stock_check.create_time.strftime('%Y-%m-%d %H:%M:%S'), 'Status:', 'Approved' if stock_check.status == 1 else 'Pending'],
            ['Remark:', stock_check.remark or '', '', '']
        ]
        
        info_table = Table(info_data, colWidths=[80, 150, 80, 150])
        info_table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('PADDING', (0, 0), (-1, -1), 6),
        ]))
        elements.append(info_table)
        elements.append(Spacer(1, 20))
        
        # 添加明细表头
        headers = ['Product Code', 'Product Name', 'System Stock', 'Actual Stock', 'Difference', 'Amount', 'Remark']
        data = [headers]
        
        # 添加明细数据
        total_amount = 0
        for detail in stock_check.details.all():
            row = [
                detail.product.code,
                detail.product.name,
                str(detail.system_stock),
                str(detail.actual_stock),
                str(detail.difference),
                str(detail.amount),
                detail.remark or ''
            ]
            data.append(row)
            total_amount += detail.amount
        
        # 添加合计行
        data.append(['Total', '', '', '', '', str(total_amount), ''])
        
        # 创建明细表格
        col_widths = [80, 150, 80, 80, 80, 100, 100]
        table = Table(data, colWidths=col_widths)
        table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('PADDING', (0, 0), (-1, -1), 6),
            ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, -1), (-1, -1), 'RIGHT'),
            ('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),
        ]))
        elements.append(table)
        
        # 生成PDF
        doc.build(elements)
        buffer.seek(0)
        
        # 创建响应
        response = HttpResponse(buffer.getvalue(), content_type='application/pdf')
        response['Content-Disposition'] = f'attachment; filename=stock_check_{stock_check.check_no}.pdf'
        return response

class StockTransferViewSet(viewsets.ModelViewSet):
    """调拨单视图集"""
    queryset = StockTransfer.objects.all()
    serializer_class = StockTransferSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination
    
    def get_permissions(self):
        if self.action in ['destroy']:
            return [IsAdminUser()]
        return [IsAuthenticated()]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        transfer_no = self.request.query_params.get('transfer_no')
        begin_time = self.request.query_params.get('beginTime')
        end_time = self.request.query_params.get('endTime')
        
        if transfer_no:
            queryset = queryset.filter(transfer_no__icontains=transfer_no)
        if begin_time:
            try:
                begin_time = datetime.strptime(begin_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__gte=begin_time)
            except ValueError:
                pass
        if end_time:
            try:
                end_time = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                queryset = queryset.filter(create_time__lte=end_time)
            except ValueError:
                pass
        
        return queryset
    
    def perform_create(self, serializer):
        serializer.save(create_user=self.request.user)
    
    @action(detail=True, methods=['post'])
    def status(self, request, pk=None):
        """更新调拨单状态"""
        status = request.data.get('status')
        if status not in [0, 1]:
            return Response({'code': 0, 'msg': '状态值无效'}, status=status.HTTP_400_BAD_REQUEST)
        
        stock_transfer = self.get_object()
        success, msg = update_stock_transfer_status(stock_transfer, status, request.user)
        if not success:
            return Response({'code': 0, 'msg': msg}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'code': 1, 'data': None})
    
    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取调拨单统计信息"""
        today = timezone.now().date()
        week_ago = today - timedelta(days=7)
        month_ago = today - timedelta(days=30)
        
        # 今日统计
        today_stats = StockTransfer.objects.filter(
            create_time__date=today
        ).aggregate(
            total_count=Count('id'),
            total_quantity=Sum('details__quantity')
        )
        
        # 本周统计
        week_stats = StockTransfer.objects.filter(
            create_time__date__gte=week_ago
        ).aggregate(
            total_count=Count('id'),
            total_quantity=Sum('details__quantity')
        )
        
        # 本月统计
        month_stats = StockTransfer.objects.filter(
            create_time__date__gte=month_ago
        ).aggregate(
            total_count=Count('id'),
            total_quantity=Sum('details__quantity')
        )
        
        return Response({
            'code': 1,
            'data': {
                'today': today_stats,
                'week': week_stats,
                'month': month_stats
            }
        })

    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出库存调拨报表"""
        # 获取查询参数
        transfer_no = request.query_params.get('transfer_no')
        begin_time = request.query_params.get('beginTime')
        end_time = request.query_params.get('endTime')
        
        # 构建查询
        queryset = self.get_queryset()
        
        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "库存调拨报表"
        
        # 设置表头样式
        header_font = Font(bold=True)
        header_fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
        header_alignment = Alignment(horizontal='center', vertical='center')
        
        # 写入表头
        headers = ['调拨单号', '商品编码', '商品名称', '调出仓库', '调入仓库', '调拨数量', 
                  '状态', '备注', '创建人', '创建时间']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
        
        # 写入数据
        row = 2
        for transfer in queryset:
            for detail in transfer.details.all():
                ws.cell(row=row, column=1).value = transfer.transfer_no
                ws.cell(row=row, column=2).value = detail.product.code
                ws.cell(row=row, column=3).value = detail.product.name
                ws.cell(row=row, column=4).value = transfer.from_warehouse
                ws.cell(row=row, column=5).value = transfer.to_warehouse
                ws.cell(row=row, column=6).value = detail.quantity
                ws.cell(row=row, column=7).value = transfer.get_status_display()
                ws.cell(row=row, column=8).value = detail.remark
                ws.cell(row=row, column=9).value = transfer.create_user.name
                ws.cell(row=row, column=10).value = transfer.create_time.strftime('%Y-%m-%d %H:%M:%S')
                row += 1
        
        # 调整列宽
        for col in ws.columns:
            max_length = 0
            column = col[0].column_letter
            for cell in col:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            adjusted_width = (max_length + 2)
            ws.column_dimensions[column].width = adjusted_width
        
        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename=stock_transfer.xlsx'
        
        # 保存工作簿
        wb.save(response)
        return response

class StockWarningViewSet(viewsets.ReadOnlyModelViewSet):
    """库存预警视图集"""
    queryset = Product.objects.filter(stock__lte=F('warning_stock'))
    serializer_class = ProductSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination
    
    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get('name')
        if name:
            queryset = queryset.filter(name__icontains=name)
        return queryset 